package de.hauschild.gmltracer.gml.impl.control;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.text.StrBuilder;

import de.hauschild.gmltracer.gml.Environment;
import de.hauschild.gmltracer.gml.Token;
import de.hauschild.gmltracer.gml.TokenStack;
import de.hauschild.gmltracer.gml.impl.AbstractToken;

/**
 * Represents a function.
 * 
 * @author Klaus Hauschild
 * @since 1.0.0
 */
public class FunctionToken extends AbstractToken {

  private final List<Token> tokenList;
  private Environment environment;

  /**
   * Instantiates a new function token.
   * 
   * @param theEnvironment
   *          the environment
   * @param theTokenList
   *          the token list
   */
  public FunctionToken(final Environment theEnvironment, final List<Token> theTokenList) {
    environment = theEnvironment;
    tokenList = theTokenList;
  }

  /**
   * Instantiates a new function.
   * 
   * @param theTokenList
   *          the token list
   */
  public FunctionToken(final List<Token> theTokenList) {
    this(new Environment(), theTokenList);
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public Token cloneToken() {
    return new FunctionToken(new Environment(environment), new ArrayList<Token>(tokenList));
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void evaluate(final Environment theEnvironment, final TokenStack theTokenStack) {
    super.evaluate(theEnvironment, theTokenStack);

    environment = new Environment(theEnvironment);
  }

  /**
   * Gets the environment.
   * 
   * @return the environment
   */
  public Environment getEnvironment() {
    return environment;
  }

  /**
   * Gets the token list.
   * 
   * @return the token list
   */
  public List<Token> getTokenList() {
    return new ArrayList<Token>(tokenList);
  }

  @Override
  public String toString() {
    final StrBuilder builder = new StrBuilder();

    builder.append("{ "); //$NON-NLS-1$
    builder.appendWithSeparators(tokenList, " "); //$NON-NLS-1$
    builder.append(" }"); //$NON-NLS-1$

    return builder.toString();
  }
}
